社交媒体应用开发教程
1. React 简介和特性
1.1 React 是什么?
React 是一个用于构建用户界面的 JavaScript 库。它由 Facebook 开发,以其高效的组件化设计和虚拟 DOM 技术而闻名。
1.2 React 的主要特性
- 组件化:React 应用由多个组件构成,每个组件负责一部分 UI。
- 虚拟 DOM:React 使用虚拟 DOM 来优化 DOM 操作,提高性能。
- 单向数据流:数据只能从父组件流向子组件,确保数据流清晰。
2. 环境搭建
2.1 安装 Node.js 和 npm
首先,确保你已经安装了 Node.js 和 npm。你可以通过以下命令检查是否安装成功:
node -v
npm -v
2.2 使用 Create React App 创建项目
Create React App 是一个官方推荐的工具,用于快速搭建 React 项目。
npx create-react-app social-media-app
cd social-media-app
npm start
3. JSX 语法
3.1 什么是 JSX?
JSX 是一种 JavaScript 的语法扩展,允许你在 JavaScript 代码中编写类似 HTML 的代码。
3.2 JSX 示例
const element = <h1>Hello, world!</h1>;
4. 组件基础
4.1 函数组件
函数组件是一个简单的 JavaScript 函数,返回 JSX。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
4.2 类组件
类组件是一个继承自 React.Component 的 JavaScript 类。
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
5. Props 和 State
5.1 Props
Props 是组件的输入参数,用于从父组件向子组件传递数据。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
5.2 State
State 是组件内部的状态,用于管理组件的动态数据。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
6. 生命周期方法
6.1 常用生命周期方法
componentDidMount:组件挂载后调用。componentDidUpdate:组件更新后调用。componentWillUnmount:组件卸载前调用。
class Clock extends React.Component {
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
7. 事件处理
7.1 事件处理示例
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = { isToggleOn: true };
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
8. 条件渲染
8.1 条件渲染示例
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
9. 列表和 Keys
9.1 列表渲染示例
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
10. 表单处理
10.1 受控组件示例
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
11. 组合 vs 继承
11.1 组合示例
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
12. 高阶组件 (HOC)
12.1 HOC 示例
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: selectData(DataSource, props)
};
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
13. Render Props
13.1 Render Props 示例
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
14. Context API
14.1 Context API 示例
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
15. Refs 和 DOM
15.1 Refs 示例
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
focusTextInput() {
this.textInput.current.focus();
}
render() {
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput.bind(this)}
/>
</div>
);
}
}
16. useState 和 useEffect
16.1 Hooks 示例
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
17. useContext
17.1 useContext 示例
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
18. useReducer
18.1 useReducer 示例
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
19. 自定义 Hooks
19.1 自定义 Hook 示例
import { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
20. Hooks 规则和最佳实践
20.1 Hooks 规则
- 只能在函数组件的顶层调用 Hooks。
- 只能在 React 函数组件中调用 Hooks。
20.2 最佳实践
- 使用
useEffect来处理副作用。 - 使用
useContext来共享全局状态。
21. Redux 基础
21.1 Redux 示例
import { createStore } from 'redux';
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'counter/incremented':
return { value: state.value + 1 }
case 'counter/decremented':
return { value: state.value - 1 }
default:
return state
}
}
let store = createStore(counterReducer)
store.subscribe(() => console.log(store.getState()))
store.dispatch({ type: 'counter/incremented' })
store.dispatch({ type: 'counter/incremented' })
store.dispatch({ type: 'counter/decremented' })
22. Redux Toolkit
22.1 Redux Toolkit 示例
import { createSlice, configureStore } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
incremented: state => {
state.value += 1;
},
decremented: state => {
state.value -= 1;
}
}
});
const store = configureStore({
reducer: counterSlice.reducer
});
store.subscribe(() => console.log(store.getState()));
store.dispatch(counterSlice.actions.incremented());
store.dispatch(counterSlice.actions.incremented());
store.dispatch(counterSlice.actions.decremented());
23. MobX 简介
23.1 MobX 示例
import { observable, action, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
class Counter {
count = 0;
constructor() {
makeObservable(this, {
count: observable,
increment: action,
decrement: action
});
}
increment() {
this.count += 1;
}
decrement() {
this.count -= 1;
}
}
const counter = new Counter();
const CounterView = observer(({ counter }) => (
<div>
<p>{counter.count}</p>
<button onClick={() => counter.increment()}>+</button>
<button onClick={() => counter.decrement()}>-</button>
</div>
));
function App() {
return <CounterView counter={counter} />;
}
24. Recoil 入门
24.1 Recoil 示例
import React from 'react';
import { RecoilRoot, atom, useRecoilState } from 'recoil';
const counterState = atom({
key: 'counterState',
default: 0,
});
function Counter() {
const [count, setCount] = useRecoilState(counterState);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
function App() {
return (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
}
25. 状态管理最佳实践
25.1 最佳实践
- 使用 Redux 或 Context API 来管理全局状态。
- 避免在组件中直接修改状态,使用 reducers 或 actions。
26. React Router 基础
26.1 React Router 示例
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
27. 动态路由
27.1 动态路由示例
<Route path="/users/:id">
<User />
</Route>
28. 嵌套路由
28.1 嵌套路由示例
function App() {
return (
<Router>
<Switch>
<Route path